package shard

import (
	"errors"
	"math"
	"sync/atomic"
)

//服务资源负载均衡
type Plotter interface {
	to(seed uint, availableResources []ShardResource, failResources []ShardResource) (*ShardResource, error)
}

//简单轮询方式服务资源负载均衡
type SimpleLoopPlotter struct {
	currentSeq uint64
}

func (v *SimpleLoopPlotter) to(seed uint, availableResources []ShardResource, failResources []ShardResource) (*ShardResource, error) {

	if availableResources == nil || len(availableResources) == 0 {
		return nil, errors.New("Have not available resources.")
	}
	size := len(availableResources)

	index := uint(math.Abs(float64(v.currentSeq % uint64(size))))
	atomic.AddUint64(&v.currentSeq, 1)
	return &availableResources[index], nil
}

//简单取模方式服务资源负载均衡
type RemainderPlotter struct {
}

func (v *RemainderPlotter) to(seed uint, availableResources []ShardResource, failResources []ShardResource) (*ShardResource, error) {

	if availableResources == nil || len(availableResources) == 0 {
		return nil, errors.New("Have not available resources.")
	}
	size := len(availableResources)
	//	fmt.Println(size)
	//	fmt.Println(cap(availableResources))
	index := uint(math.Abs(float64(seed % uint(size))))
	return &availableResources[index], nil
}
